home *** CD-ROM | disk | FTP | other *** search
/ Shareware Super Platinum 8 / Shareware Super Platinum 8.iso / mac / PROGTOOL / FLI106C.ZIP;1 / FLIHELP.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1992-03-12  |  14.8 KB  |  647 lines

  1. //
  2. // The Fusion Library Interface for DOS
  3. // Version 1.06c
  4. // Copyright (C) 1990, 1991, 1992
  5. // Software Dimensions
  6. //
  7. // FusionHelp
  8. // Context Sensitive Help
  9. //
  10.  
  11. #include "fli.h"
  12. #include "elements.h"
  13. #include "colors.h"
  14.  
  15. #ifdef __BCPLUSPLUS__
  16. #pragma hdrstop
  17. #endif
  18.  
  19. #pragma warn -inl
  20.  
  21. #include <io.h>
  22. #include <fcntl.h>
  23. #include <sys\stat.h>
  24. #include <string.h>
  25. #include <alloc.h>
  26. #include <mem.h>
  27.  
  28. #pragma warn -par
  29. #pragma warn -use
  30.  
  31. static char EndCopyRight[] = "FusionHelp 1.00 (c) Software Dimensions";
  32.  
  33. static char HelpFile[80] = "FUSION.HLP";
  34.  
  35. int HelpSystemAvailable=0; // Is help available (i.e. the help file)
  36. int DisabledHelp=0; // Was the help system shut off by the programmer?
  37.  
  38. //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  39. //
  40. // class HelpLister -- another illustration of how to create a quick element
  41. //
  42. // This class handles the display of help through a dialog
  43. //
  44. //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  45.  
  46. class HelpLister : public DialogElement
  47. {
  48. protected:
  49.  
  50.   int &ItemCount;
  51.   char **Items;
  52.   int ItemAtTopOfList;
  53.   int Widest;
  54.   int OffsetFromLeft;
  55.  
  56. public:
  57.  
  58.   HelpLister(int _X,int _Y,int _Width,int _Height,int &_ItemCount,char **_Items) :
  59.       ItemCount(_ItemCount),
  60.       Items(_Items)
  61.   {
  62.     X=_X;
  63.     Y=_Y;
  64.     Width=_Width+3;
  65.     Height=_Height+1;
  66.     ItemAtTopOfList=0;
  67.     OffsetFromLeft=0;
  68.     Widest=0;
  69.     for (int i=0;i<_ItemCount;i++)
  70.       if (strlen(_Items[i])>Widest)
  71.         Widest=strlen(Items[i]);
  72.   }
  73.  
  74.   void Show()
  75.   {
  76.     MouseHide();
  77.  
  78.     Blaze->EraseArea(X,Y,Width-1,Height,Colors.PickText);
  79.     Blaze->CharacterRepeaterDown(X+Width-1,Y,Height-1,Colors.PickButton,0xb1);
  80.     Blaze->CharacterRepeater(X,Y+Height-1,Width-1,Colors.PickButton,0xb1);
  81.  
  82.     (*Blaze) (X+Width-1,Y)
  83.       << Colors.PickButton
  84.       << '\x1e';
  85.  
  86.     (*Blaze) (X+Width-1,Y+Height-2)
  87.       << '\x1f';
  88.  
  89.     (*Blaze) (X,Y+Height-1)
  90.       << '\x11';
  91.  
  92.     (*Blaze) (X+Width-2,Y+Height-1)
  93.       << '\x10';
  94.  
  95.     if (ItemCount && ItemCount>Height-3)
  96.     {
  97.       int Calc=Height-3;
  98.  
  99.       if (ItemCount)
  100.       {
  101.         ItemCount-=(Height-1);
  102.  
  103.         int Determine=ItemCount/Calc;
  104.         int AnotherDetermine=0;
  105.         if (ItemAtTopOfList && Determine)
  106.           AnotherDetermine=ItemAtTopOfList/Determine;
  107.  
  108.         ItemCount+=(Height-1);
  109.  
  110.         if (AnotherDetermine>=Height-3)
  111.           AnotherDetermine=Height-4;
  112.  
  113.         (*Blaze) (X+Width-1,Y+1+AnotherDetermine)
  114.           << '\xfe';
  115.       }
  116.     }
  117.  
  118.     if (Widest && Widest>Width-3)
  119.     {
  120.       int Calc=Width-3;
  121.  
  122.       int Determine=Widest/Calc;
  123.       int AnotherDetermine=0;
  124.       if (OffsetFromLeft && Determine)
  125.         AnotherDetermine=OffsetFromLeft/Determine;
  126.  
  127.       if (AnotherDetermine>=Width-3)
  128.         AnotherDetermine=Width-4;
  129.  
  130.       (*Blaze) (X+1+AnotherDetermine,Y+Height-1)
  131.         << '\xfe';
  132.     }
  133.  
  134.     int LocX=0, LocY=0, LocWide=0, LocHigh=0;
  135.  
  136.     Blaze->WindowInformation(LocX,LocY,LocWide,LocHigh);
  137.  
  138.     BlazeClass Blaze;
  139.     Blaze.Window(LocX+X,LocY+Y,Width-2,Height);
  140.     +Blaze;
  141.     !Blaze;
  142.  
  143.     if (ItemCount)
  144.       for (int i=0;i<Height-1;i++)
  145.       {
  146.         if (OffsetFromLeft<strlen(Items[ItemAtTopOfList+i]))
  147.           Blaze (1,i)
  148.             << Colors.PickText
  149.             << (Items[ItemAtTopOfList+i]+OffsetFromLeft);
  150.  
  151.         if (ItemAtTopOfList+i==ItemCount-1)
  152.           break;
  153.       }
  154.  
  155.     MouseShow();
  156.   }
  157.  
  158.   void HighLight()
  159.   {
  160.     Blaze->WindowGotoXY(X+1,Y);
  161.   }
  162.  
  163.   int EventHandler(int Event)
  164.   {
  165.     if (Event==kbDown ||
  166.       (Event==ValidatedMousedEvent
  167.         && (MouseEvent&MouseLeftButtonRelease || MouseEvent&MouseHeldDown)
  168.         && MouseHorizontal==X+Width-1
  169.         && MouseVertical==Y+Height-2))
  170.     {
  171.       if (ItemCount && ItemAtTopOfList+Height-1<ItemCount)
  172.       {
  173.         ItemAtTopOfList++;
  174.         if (ItemAtTopOfList>=ItemCount)
  175.         {
  176.           ItemAtTopOfList--;
  177.           return CompleteEvent;
  178.         }
  179.         Show();
  180.         HighLight();
  181.       }
  182.       return CompleteEvent;
  183.     }
  184.  
  185.     if (Event==kbUp ||
  186.       (Event==ValidatedMousedEvent
  187.         && (MouseEvent&MouseLeftButtonRelease || MouseEvent&MouseHeldDown)
  188.         && MouseHorizontal==X+Width-1
  189.         && MouseVertical==Y))
  190.     {
  191.       if (ItemCount)
  192.       {
  193.         ItemAtTopOfList--;
  194.         if (ItemAtTopOfList<0)
  195.         {
  196.           ItemAtTopOfList++;
  197.           return CompleteEvent;
  198.         }
  199.         Show();
  200.         HighLight();
  201.       }
  202.       return CompleteEvent;
  203.     }
  204.  
  205.     if (Widest>Width-3 && (Event==kbRight ||
  206.       (Event==ValidatedMousedEvent
  207.         && (MouseEvent&MouseLeftButtonRelease || MouseEvent&MouseHeldDown)
  208.         && MouseHorizontal==X+Width-2
  209.         && MouseVertical==Y+Height-1)))
  210.     {
  211.       if (OffsetFromLeft>=Widest)
  212.         return CompleteEvent;
  213.       else
  214.         OffsetFromLeft++;
  215.       Show();
  216.       HighLight();
  217.       return CompleteEvent;
  218.     }
  219.  
  220.     if (OffsetFromLeft && (Event==kbLeft ||
  221.       (Event==ValidatedMousedEvent
  222.         && (MouseEvent&MouseLeftButtonRelease || MouseEvent&MouseHeldDown)
  223.         && MouseHorizontal==X
  224.         && MouseVertical==Y+Height-1)))
  225.     {
  226.       OffsetFromLeft--;
  227.       Show();
  228.       HighLight();
  229.       return CompleteEvent;
  230.     }
  231.  
  232.     if (MouseButtonStatus&LeftButton && ItemCount && ItemCount>Height-3 && Height>3 &&
  233.       MouseHorizontal==X+Width-1 && MouseVertical>Y && MouseVertical<Y+Height-2)
  234.     {
  235.       int Block=MouseVertical-Y-1;
  236.  
  237.       int Calc=Height-3;
  238.  
  239.       ItemCount-=(Height-1);
  240.  
  241.       if (!ItemCount)
  242.         return CompleteEvent;
  243.  
  244.       int Determine=ItemCount/Calc;
  245.       int AnotherDetermine=Block*Determine;
  246.  
  247.       ItemCount+=(Height-1);
  248.  
  249.       ItemAtTopOfList=AnotherDetermine;
  250.  
  251.       if (ItemAtTopOfList+Height-1>ItemCount || Block==Height-4)
  252.         ItemAtTopOfList=(ItemCount-Height)+1;
  253.  
  254.       if (ItemAtTopOfList<0)
  255.         ItemAtTopOfList=0;
  256.  
  257.       Show();
  258.       HighLight();
  259.  
  260.       return CompleteEvent;
  261.     }
  262.  
  263.     if (MouseButtonStatus&LeftButton && Widest>Width-3 &&
  264.       MouseVertical==Y+Height-1 && MouseHorizontal>X && MouseHorizontal<X+Width-2)
  265.     {
  266.       int Block=MouseHorizontal-X-1;
  267.  
  268.       int Calc=Width-3;
  269.  
  270.       int Determine=Widest/Calc;
  271.       int AnotherDetermine=Block*Determine;
  272.       if (AnotherDetermine>Widest)
  273.         AnotherDetermine=Widest-1;
  274.  
  275.       OffsetFromLeft=AnotherDetermine;
  276.  
  277.       Show();
  278.       HighLight();
  279.  
  280.       return CompleteEvent;
  281.     }
  282.  
  283.     if (Event==ValidatedMousedEvent && MouseEvent&MouseDoubleClick)
  284.       return StopEvent;
  285.  
  286.     return Event;
  287.   }
  288. };
  289.  
  290. //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  291. //
  292. // class HelpConnections
  293. //
  294. // This class connects the help control file before the program starts
  295. //
  296. //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  297.  
  298. class HelpConnections
  299. {
  300.   public:
  301.  
  302.   HelpConnections()
  303.   {
  304.     if (!access(HelpFile,0))
  305.       HelpSystemAvailable=1;
  306.   }
  307. };
  308.  
  309. static HelpConnections MakeTheConnection;
  310.  
  311. //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  312. //
  313. // FusionHelp()
  314. //
  315. // Constructor
  316. //
  317. //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  318.  
  319. FusionHelp::FusionHelp()
  320. {
  321.   HelpId=0;
  322. }
  323.  
  324. //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  325. //
  326. // DefineHelp()
  327. //
  328. // Define an alternate help file
  329. //
  330. //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  331.  
  332. int FusionHelp::DefineHelp(char *HelpFileName)
  333. {
  334.   if (!access(HelpFileName,0))
  335.   {
  336.     strcpy(HelpFile,HelpFileName);
  337.     HelpSystemAvailable=1;
  338.     return 1;
  339.   }
  340.   else
  341.   {
  342.     HelpSystemAvailable=0;
  343.     return 0;
  344.   }
  345. }
  346.  
  347. //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  348. //
  349. // DisableHelp()
  350. //
  351. // Disables the help system
  352. //
  353. //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  354.  
  355. void FusionHelp::DisableHelp()
  356. {
  357.   DisabledHelp=1;
  358. }
  359.  
  360. //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  361. //
  362. // HelpDialog class
  363. //
  364. // Defines the event handler for a help system
  365. //
  366. //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  367.  
  368. const winAcceptButton=995;
  369.  
  370. class HelpDialog : public DialogClass
  371. {
  372. public:
  373.  
  374.   HelpDialog(int Width,int Height,char *Title) :
  375.     DialogClass(Width,Height,Title) { }
  376.  
  377.   int EventHandler(int Event)
  378.   {
  379.     if (Event==kbEsc ||
  380.         Event==kbCr ||
  381.         Event==CloseEvent ||
  382.         Event==OutsideEvent ||
  383.         Event==winAcceptButton)
  384.       return StopEvent;
  385.     return CompleteEvent;
  386.   }
  387. };
  388.  
  389. //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  390. //
  391. // RequestHelp()
  392. //
  393. // Request help by calling the help system directly
  394. //
  395. //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  396.  
  397. void FusionHelp::RequestHelp(int Help)
  398. {
  399.   int SaveHelp=HelpId;
  400.  
  401.   HelpId=Help;
  402.   EngageHelp();
  403.   HelpId=SaveHelp;
  404. }
  405.  
  406. //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  407. //
  408. // EngageHelp()
  409. //
  410. // Define an alternate help file
  411. //
  412. //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  413.  
  414. void FusionHelp::EngageHelp()
  415. {
  416.   if (DisabledHelp)
  417.     return;
  418.  
  419.   if (HelpSystemAvailable && HelpId)
  420.   {
  421.     if (HelpId>0 && HelpId<1000)
  422.       return;
  423.  
  424.     if (access(HelpFile,0))
  425.       goto HelpMissing;
  426.  
  427.     int Help=_open(HelpFile,O_RDONLY|O_BINARY|O_DENYWRITE);
  428.  
  429.     lseek(Help,0,SEEK_SET);
  430.  
  431.     char CopyRightCheck[sizeof(EndCopyRight)+1];
  432.  
  433.     read(Help,&CopyRightCheck,sizeof(EndCopyRight));
  434.  
  435.     if (memcmp(EndCopyRight,CopyRightCheck,sizeof(EndCopyRight)))
  436.     {
  437.       close(Help);
  438.       InfoBox &NotAvailable = *new InfoBox;
  439.       NotAvailable
  440.             + "The help file is damaged and contains"
  441.             + "an incorrect signature.  As a result"
  442.             + "the help system is not available.";
  443.       NotAvailable.Title("Help Failure");
  444.       NotAvailable.UseInfoBox();
  445.       delete &NotAvailable;
  446.       return;
  447.     }
  448.  
  449.     lseek(Help,sizeof(EndCopyRight),SEEK_SET);
  450.  
  451.     int AvailableHelps=0;
  452.  
  453.     read(Help,&AvailableHelps,sizeof(int));
  454.  
  455.     struct _HelpLocator
  456.     {
  457.       int Identifier;
  458.       long Locator;
  459.     } Location;
  460.  
  461.     for (int i=0;i<AvailableHelps;i++)
  462.     {
  463.       read(Help,&Location,sizeof(_HelpLocator));
  464.  
  465.       if (Location.Identifier==HelpId)
  466.         goto Accepted;
  467.     }
  468.  
  469.     close(Help);
  470.  
  471.     {
  472.     InfoBox &NotAvailable = *new InfoBox;
  473.     NotAvailable
  474.           + "The help for this option appears"
  475.           + "to be missing.";
  476.     NotAvailable.Title("Help Failure");
  477.     NotAvailable.UseInfoBox();
  478.     delete &NotAvailable;
  479.     }
  480.  
  481.     return;
  482.  
  483. Accepted:
  484.  
  485.     lseek(Help,Location.Locator,SEEK_SET);
  486.  
  487.     long TotalSize;
  488.  
  489.     read(Help,&TotalSize,sizeof(long));
  490.     
  491.     #pragma warn -sig
  492.     char *Storage=new char[TotalSize];
  493.     read(Help,Storage,TotalSize);
  494.     #pragma warn .sig
  495.  
  496.     close(Help);
  497.  
  498.     //------------------------------------------------------------------------
  499.     //
  500.     // Interpret the help file
  501.     //
  502.     //------------------------------------------------------------------------
  503.  
  504.     char **LineStorage=0;
  505.  
  506.     int Count=0;
  507.  
  508.     char Stuffer[300];
  509.  
  510.     int CurrentWidth=0;
  511.  
  512.     Stuffer[0]=0;
  513.  
  514.     char BlankLine[2]="\0";
  515.  
  516.     int TabActive=0;
  517.  
  518.     for (int j=0;j<TotalSize;j++)
  519.     {
  520.       if (*(Storage+j)=='\t')
  521.       {
  522.         TabActive++;
  523.         if (CurrentWidth)
  524.         {
  525.           Count++;
  526.           LineStorage=(char**)realloc(LineStorage,Count*sizeof(char*));
  527.           LineStorage[Count-1]=new char[CurrentWidth+1];
  528.           strcpy(LineStorage[Count-1],Stuffer);
  529.         }
  530.         Stuffer[0]=0;
  531.         CurrentWidth=0;
  532.         continue;
  533.       }
  534.  
  535.       if (*(Storage+j)=='\r')
  536.       {
  537.         if (!CurrentWidth)
  538.         {
  539.           TabActive=0;
  540.           Count++;
  541.           LineStorage=(char**)realloc(LineStorage,Count*sizeof(char*));
  542.           LineStorage[Count-1]=BlankLine;
  543.         }
  544.         else
  545.         {
  546.           if (TabActive)
  547.           {
  548.             Count++;
  549.             LineStorage=(char**)realloc(LineStorage,Count*sizeof(char*));
  550.             LineStorage[Count-1]=new char[CurrentWidth+1];
  551.             strcpy(LineStorage[Count-1],Stuffer);
  552.           }
  553.           else
  554.           {
  555.             Count+=2;
  556.             LineStorage=(char**)realloc(LineStorage,Count*sizeof(char*));
  557.             LineStorage[Count-2]=new char[CurrentWidth+1];
  558.             strcpy(LineStorage[Count-2],Stuffer);
  559.             LineStorage[Count-1]=BlankLine;
  560.           }
  561.           Stuffer[0]=0;
  562.           CurrentWidth=0;
  563.           TabActive=0;
  564.         }
  565.       }
  566.       else
  567.       {
  568.         Stuffer[CurrentWidth]=*(Storage+j);
  569.         Stuffer[++CurrentWidth]=0;
  570.  
  571.         if (CurrentWidth==53 && !TabActive)
  572.         {
  573.           if (Stuffer[CurrentWidth-1]!=' ')
  574.           {
  575.             do Stuffer[CurrentWidth]=0;
  576.               while(Stuffer[--CurrentWidth]!=' ');
  577.             Stuffer[CurrentWidth]=0;
  578.             do j--;
  579.               while(*(Storage+j)!=' ');
  580.             Count++;
  581.             LineStorage=(char**)realloc(LineStorage,Count*sizeof(char*));
  582.             LineStorage[Count-1]=new char[CurrentWidth+1];
  583.             strcpy(LineStorage[Count-1],Stuffer);
  584.           }
  585.           else
  586.           {
  587.             Count++;
  588.             LineStorage=(char**)realloc(LineStorage,Count*sizeof(char*));
  589.             LineStorage[Count-1]=new char[CurrentWidth+1];
  590.             strcpy(LineStorage[Count-1],Stuffer);
  591.           }
  592.           Stuffer[0]=0;
  593.           CurrentWidth=0;
  594.         }
  595.       }
  596.     }
  597.  
  598.     if (CurrentWidth)
  599.     {
  600.       Count++;
  601.       LineStorage=(char**)realloc(LineStorage,Count*sizeof(char*));
  602.       LineStorage[Count-1]=new char[CurrentWidth+1];
  603.       strcpy(LineStorage[Count-1],Stuffer);
  604.     }
  605.  
  606.     delete Storage;
  607.  
  608.     HelpDialog &Dialog=*new HelpDialog(60,16,"Help");
  609.  
  610.     Dialog.Element(new HelpLister(1,1,53,9,Count,LineStorage));
  611.     Dialog.Help("This is the help you requested");
  612.  
  613.     Dialog.Element(new DiaPushButton(26,12,"~Okay",winAcceptButton,kbAltO));
  614.     Dialog.Help("Close the help system and return to the program");
  615.  
  616.     Dialog.UseDialog();
  617.  
  618.     delete &Dialog;
  619.  
  620.     for (i=0;i<Count;i++)
  621.     {
  622.       if (LineStorage[i]!=BlankLine)
  623.         delete LineStorage[i];
  624.     }
  625.  
  626.     free(LineStorage);
  627.  
  628.     return;
  629.   }
  630.  
  631.   if (!HelpSystemAvailable)
  632.   {
  633.  
  634. HelpMissing:
  635.  
  636.     InfoBox &NotAvailable = *new InfoBox;
  637.     NotAvailable
  638.           + "The help file is missing.  As a result"
  639.           + "the help system is not available.";
  640.     NotAvailable.Title("Help Failure");
  641.     NotAvailable.UseInfoBox();
  642.     delete &NotAvailable;
  643.   }
  644. }
  645.  
  646. #pragma warn .inl
  647.